/**
 * $Revision: 1.0 $
 * $Author: Eric Yang $
 * $Date: Aug 7, 2009 10:38:54 PM $
 *
 * Author: Eric Yang
 * Date  : Aug 7, 2009 10:38:54 PM
 *
 */
package com.gooex.service.base.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.hibernate.Query;
import org.c4j.string.StringTools;
import org.c4j.system.web.exception.ServiceException;
import org.c4j.system.web.page.Page;

import com.gooex.domain.base.Category;
import com.gooex.domain.base.Product;
import com.gooex.domain.base.Property;
import com.gooex.domain.base.PropertyValue;
import com.gooex.domain.organization.User;
import com.gooex.service.BaseAppHibernateService;
import com.gooex.service.base.ICategoryManager;
import com.gooex.service.base.IProductManager;
import com.gooex.service.base.exception.ExceptionCode;
import com.gooex.service.base.exception.ProductException;

/**
 * @author Eric Yang
 * @version 1.0
 */
public class ProductManagerImpl extends BaseAppHibernateService implements IProductManager {
	private ICategoryManager categoryManager;

	public Product getProduct(String id) {
		if (StringTools.isBlankOrNull(id))
			return null;
		return (Product) getHibernateTemplate().get(Product.class, id);
	}

	public Product loadProduct(String id) {
		if (StringTools.isBlankOrNull(id))
			throw new ServiceException(ExceptionCode.OPERATION_NOT_ALLOWED, "");
		Product product = (Product) getHibernateTemplate().load(Product.class, id);
		if (product == null)
			throw new ServiceException(ExceptionCode.PRODUCT_NOT_EXISTS, "");
		return product;
	}

	public List<Product> getProducts() {
		return getHibernateTemplate().find("from Product");
	}

	public Product getProductByName(String name) {
		String hql = "from " + Product.class.getName() + " where name=?";
		List<Product> products = getHibernateTemplate().find(hql, name);
		if (products != null && products.size() == 1)
			return products.get(0);
		return null;
	}

	public void saveProduct(Product product) {
		if (StringTools.isBlankOrNull(product.getId())) {
			product.setId(null);
			product.setUser(getCurrentUser());
		}
		if (product.getCategory() != null && StringTools.isBlankOrNull(product.getCategory().getName())) {
			Category category = categoryManager.getCategory(product.getCategory().getId());
			product.setCategory(category);
		}
		product.setUpdateTime(new Date());
		getHibernateTemplate().saveOrUpdate(product);
	}

	public void removeProduct(Product product) throws ProductException {
		product = getProduct(product.getId());
		getHibernateTemplate().delete(product);
	}

	public List<Product> findProducts(List<PropertyValue> values) {
		return null;
	}

	public List<Product> findProductsByName(String name, Page page) {
		String queryString = "from " + Product.class.getName() + " where name like ?";
		Object[] params = new Object[] { "%" + name + "%" };
		return findHQLQuery(queryString, params, page);
	}

	public List<Product> getProducts(User user) {
		if (user == null)
			return null;
		Query query = getSession().createQuery("from Product where user.id=:userId");
		query.setParameter("userId", user.getId());
		return query.list();
	}

	public List<Product> getProducts(User user, boolean raw) {
		if (user == null)
			return null;
		Query query = getSession().createQuery("from Product  where raw=:raw and user.id=:userId");
		query.setCacheable(true);
		query.setParameter("raw", raw);
		query.setParameter("userId", user.getId());
		return query.list();
	}

	public List<Product> getProducts(Category category, User user, boolean raw) {
		String hql = " from " + Product.class.getName() + " where raw=?";
		List<Object> params = new ArrayList<Object>();
		params.add(raw);

		if (category != null && category.getId() != null) {
			hql += " and category.id = ?";
			params.add(category.getId());
		}
		if (user != null) {
			hql += " and user.id = ?";
			params.add(user.getId());
		}

		return findHQLQuery(hql, params.toArray(), null);
	}

	public List<Product> getProducts(Category category, String keyword, Page page, boolean raw) {
		String hql = " from " + Product.class.getName() + " where raw=?";
		List<Object> params = new ArrayList<Object>();
		params.add(raw);
		if (category != null && category.getId() != null) {
			hql += " and ( category.id = ? or category.parent.id = ? )";
			params.add(category.getId());
			params.add(category.getId());
		}

		if (keyword != null) {
			hql += " and keyword like ?";
			params.add("%" + keyword + "%");
		}

		return findHQLQuery(hql, params.toArray(), page);
	}

	public void setCategoryManager(ICategoryManager categoryManager) {
		this.categoryManager = categoryManager;
	}

	public List<Product> getTopNewProducts(int number) {
		Query query = getSession().createQuery("from " + Product.class.getName() + " where raw =:raw");
		query.setCacheable(true);
		query.setParameter("raw", false);
		query.setFirstResult(0);
		query.setMaxResults(number);
		return query.list();
	}

	public void updateProperty(Product product, List<Property> properties) {
	}

	public void saveProperty(Product product, Property property) {
	}

	public List<Product> getProducts(String keyword, Page page) {
		return getProducts(null, keyword, page, false);
	}

	public List<Product> getProducts(String keyword, Page page, boolean raw) {
		return getProducts(null, keyword, page, raw);
	}

	public List<Product> getProducts(Category category, Page page) {
		return getProducts(category, null, page, false);
	}

	public List<Product> getProducts(Category category, Page page, boolean raw) {
		return getProducts(category, null, page, raw);
	}

	public List<Product> getProducts(Category category, String keyword, Page page) {
		return getProducts(category, keyword, page, false);
	}

}
